package com.mh.service;

import com.mh.dao.InvoiceDAO;
import com.mh.dao.ItemDAO;
import com.mh.dao.ProductDAO;

import com.mh.domain.Invoice;
import com.mh.domain.Item;
import com.mh.domain.Product;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for Item entities
 * 
 */

@Service("ItemService")
@Transactional
public class ItemServiceImpl implements ItemService {

	/**
	 * DAO injected by Spring that manages Invoice entities
	 * 
	 */
	@Autowired
	private InvoiceDAO invoiceDAO;

	/**
	 * DAO injected by Spring that manages Item entities
	 * 
	 */
	@Autowired
	private ItemDAO itemDAO;

	/**
	 * DAO injected by Spring that manages Product entities
	 * 
	 */
	@Autowired
	private ProductDAO productDAO;

	/**
	 * Instantiates a new ItemServiceImpl.
	 *
	 */
	public ItemServiceImpl() {
	}

	/**
	 */
	@Transactional
	public Item findItemByPrimaryKey(Integer id) {
		return itemDAO.findItemByPrimaryKey(id);
	}

	/**
	 * Delete an existing Item entity
	 * 
	 */
	@Transactional
	public void deleteItem(Item item) {
		itemDAO.remove(item);
		itemDAO.flush();
	}

	/**
	 * Delete an existing Invoice entity
	 * 
	 */
	@Transactional
	public Item deleteItemInvoice(Integer item_id, Integer related_invoice_id) {
		Item item = itemDAO.findItemByPrimaryKey(item_id, -1, -1);
		Invoice related_invoice = invoiceDAO.findInvoiceByPrimaryKey(related_invoice_id, -1, -1);

		item.setInvoice(null);
		related_invoice.getItems().remove(item);
		item = itemDAO.store(item);
		itemDAO.flush();

		related_invoice = invoiceDAO.store(related_invoice);
		invoiceDAO.flush();

		invoiceDAO.remove(related_invoice);
		invoiceDAO.flush();

		return item;
	}

	/**
	 * Save an existing Item entity
	 * 
	 */
	@Transactional
	public void saveItem(Item item) {
		Item existingItem = itemDAO.findItemByPrimaryKey(item.getId());

		if (existingItem != null) {
			if (existingItem != item) {
				existingItem.setId(item.getId());
				existingItem.setQuantity(item.getQuantity());
				existingItem.setCost(item.getCost());
				existingItem.setCreatedBy(item.getCreatedBy());
				existingItem.setCreatedOn(item.getCreatedOn());
				existingItem.setModifiedBy(item.getModifiedBy());
				existingItem.setModifiedOn(item.getModifiedOn());
			}
			item = itemDAO.store(existingItem);
		} else {
			item = itemDAO.store(item);
		}
		itemDAO.flush();
	}

	/**
	 * Return a count of all Item entity
	 * 
	 */
	@Transactional
	public Integer countItems() {
		return ((Long) itemDAO.createQuerySingleResult("select count(o) from Item o").getSingleResult()).intValue();
	}

	/**
	 * Return all Item entity
	 * 
	 */
	@Transactional
	public List<Item> findAllItems(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Item>(itemDAO.findAllItems(startResult, maxRows));
	}

	/**
	 * Save an existing Product entity
	 * 
	 */
	@Transactional
	public Item saveItemProduct(Integer id, Product related_product) {
		Item item = itemDAO.findItemByPrimaryKey(id, -1, -1);
		Product existingproduct = productDAO.findProductByPrimaryKey(related_product.getId());

		// copy into the existing record to preserve existing relationships
		if (existingproduct != null) {
			existingproduct.setId(related_product.getId());
			existingproduct.setName(related_product.getName());
			existingproduct.setPrice(related_product.getPrice());
			existingproduct.setCreatedBy(related_product.getCreatedBy());
			existingproduct.setCreatedOn(related_product.getCreatedOn());
			existingproduct.setModifiedBy(related_product.getModifiedBy());
			existingproduct.setModifiedOn(related_product.getModifiedOn());
			related_product = existingproduct;
		}

		item.setProduct(related_product);
		related_product.getItems().add(item);
		item = itemDAO.store(item);
		itemDAO.flush();

		related_product = productDAO.store(related_product);
		productDAO.flush();

		return item;
	}

	/**
	 * Delete an existing Product entity
	 * 
	 */
	@Transactional
	public Item deleteItemProduct(Integer item_id, Integer related_product_id) {
		Item item = itemDAO.findItemByPrimaryKey(item_id, -1, -1);
		Product related_product = productDAO.findProductByPrimaryKey(related_product_id, -1, -1);

		item.setProduct(null);
		related_product.getItems().remove(item);
		item = itemDAO.store(item);
		itemDAO.flush();

		related_product = productDAO.store(related_product);
		productDAO.flush();

		productDAO.remove(related_product);
		productDAO.flush();

		return item;
	}

	/**
	 * Load an existing Item entity
	 * 
	 */
	@Transactional
	public Set<Item> loadItems() {
		return itemDAO.findAllItems();
	}

	/**
	 * Save an existing Invoice entity
	 * 
	 */
	@Transactional
	public Item saveItemInvoice(Integer id, Invoice related_invoice) {
		Item item = itemDAO.findItemByPrimaryKey(id, -1, -1);
		Invoice existinginvoice = invoiceDAO.findInvoiceByPrimaryKey(related_invoice.getId());

		// copy into the existing record to preserve existing relationships
		if (existinginvoice != null) {
			existinginvoice.setId(related_invoice.getId());
			existinginvoice.setDocument(related_invoice.getDocument());
			existinginvoice.setTotal(related_invoice.getTotal());
			existinginvoice.setCreatedBy(related_invoice.getCreatedBy());
			existinginvoice.setCreatedOn(related_invoice.getCreatedOn());
			existinginvoice.setModifiedBy(related_invoice.getModifiedBy());
			existinginvoice.setModifiedOn(related_invoice.getModifiedOn());
			related_invoice = existinginvoice;
		}

		item.setInvoice(related_invoice);
		related_invoice.getItems().add(item);
		item = itemDAO.store(item);
		itemDAO.flush();

		related_invoice = invoiceDAO.store(related_invoice);
		invoiceDAO.flush();

		return item;
	}
}
